package generator;

import bean.ClassConfigBean;
import com.intellij.ide.impl.ProjectUtil;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.impl.file.PsiDirectoryImpl;
import org.jetbrains.annotations.Nullable;
import utils.CommonUtil;
import utils.FileUtil;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class ClassGenerator {

    private static final class GeneratorHolder {
        private static final ClassGenerator generator = new ClassGenerator();
    }

    public static ClassGenerator getInstance() {
        return GeneratorHolder.generator;
    }

    public static boolean generate(PsiDirectory nowSelect, Map<String, String> fileKeyMap, ClassConfigBean... classConfigBeans) {
        List<File> generateFiles = new LinkedList<>();
        for (int i = 0; i < classConfigBeans.length; i++) {
            ClassConfigBean config = classConfigBeans[i];
            String content = getInstance().readTemplateFile(config.getTemplateFile(), fileKeyMap);
            int finalI = i;
            WriteCommandAction.runWriteCommandAction(nowSelect.getProject(), () -> {
                File file = config.createFile(nowSelect);
                if (file != null) {
                    generateFiles.add(file);
                    FileUtil.writeStringToFile(file, content);
                }
                if (finalI == classConfigBeans.length - 1) {
                    ProjectUtil.tryOpenFileList(nowSelect.getProject(), generateFiles, "");
                }
            });
        }
        return true;
    }

    private String readTemplateFile(String fileName, Map<String, String> keyMap) {
        InputStream in = this.getClass().getResourceAsStream(fileName);
        String content = "";
        try {
            byte[] src = readStream(in);
            content = new String(src);
        } catch (IOException e) {
            e.printStackTrace();
            CommonUtil.showError("文件读取失败：" + fileName);
        }
        for (Map.Entry<String, String> entry : keyMap.entrySet()) {
            content = content.replace(entry.getKey(), entry.getValue());
        }
        return content;
    }

    /**
     * 读取数据
     */
    private byte[] readStream(@Nullable InputStream inputStream) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            byte[] buffer = new byte[1024];
            int len;
            while (inputStream != null && (len = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return outputStream.toByteArray();
    }
}
